/**
 * Copyright (c) 2019-2021,  陈俊兵 (cjb6b.com@gmail.com)
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.ktjiaoyu.thread.sync;

import java.util.ArrayList;
import java.util.Collection;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 公平锁测试
 *
 * @author 陈俊兵 (cjb6b.com@gmail.com)
 * @version 1.0.0
 * @packageName com.ktjiaoyu.mianshi.thread
 * @fileName FairLockTest.java
 * @createTime 2020/10/5 10:47
 * @lastModify 2020/10/5 10:47
 */
public class FairLockTest {

    public static void main(String[] args) {
        // 使用fair参数指定为公平锁
        MyReentrantLock fairLock = new MyReentrantLock(true);
        // 非公平锁
        MyReentrantLock nonFairLock = new MyReentrantLock(false);
        testLock(fairLock);
    }

    public static void testLock(MyReentrantLock lock) {
        for (int i = 0; i < 10; i++) {
            Thread t = new Thread(() -> {
                synchronized (lock) {
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                for (int j = 0; j < 2; j++) {
                    try {
                        lock.lock();
                        System.out.print("当前执行线程：[" + Thread.currentThread().getName() + "], 其他等待线程 [");
                        ArrayList<Thread> list = (ArrayList<Thread>) lock.getQueuedThreads();
                        for (int k = 0; k < list.size(); k++) {
                            System.out.print(list.get(k).getName());
                            if (k != list.size() - 1) {
                                System.out.print(",");
                            }
                        }
                        System.out.println("]");

                    } catch (Exception e) {
                        e.printStackTrace();
                    } finally {
                        lock.unlock();
                    }
                }

            }, String.valueOf(i));
            try {
                t.start();
                Thread.sleep(1);// 保证所有线程是按顺序启动
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        synchronized (lock) {

            lock.notifyAll();
        }
    }

    /**
     * 内部类
     */
    private static class MyReentrantLock extends ReentrantLock {
        public MyReentrantLock(boolean fair) {
            super(fair);
        }

        // 把getQueuedThreads方法公共化
        @Override
        public Collection<Thread> getQueuedThreads() {
            return super.getQueuedThreads();
        }
    }

}
